package com.gopay.solution.domain.bo.impl;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import com.gopay.common.constants.poundage.FeeDtlStatus;
import com.gopay.common.constants.poundage.FeeType;
import com.gopay.common.constants.txncd.IntTxnCd;
import com.gopay.common.domain.solution.GpRiskFundReq;
import com.gopay.common.util.NumberUtils;
import com.gopay.solution.domain.po.SolutionRuleDtl;
import com.gopay.solution.domain.po.SsGpRiskFundConfDtl;
import com.gopay.solution.domain.vo.Event;
import com.gopay.solution.domain.vo.Result;

/**
 * 风险金额度方案规则执行器
 * @SsGpRiskFundSoluRuleExecutor.java
 * @author Ryan
 * @2014年4月18日 下午3:48:00  www.gopay.com.cn Inc.All rights reserved.
 */
@Service(value = "ssGpRiskFundSoluRuleExecutor")
public class SsGpRiskFundSoluRuleExecutor extends AbstractSolutionRuleExecutor {

    @Override
    public Result execute(List<SolutionRuleDtl> rules, Event event) {

        

        Result res = new Result();
        res.setSolved(false);
        res.setFailedReason("");
        res.setDetail(null);

        if (null == rules || rules.isEmpty()) {
            res.setFailedReason("查询不到风险金方案记录");
            return res;
        }

        Serializable input = event.getDetail();

        GpRiskFundReq req = (GpRiskFundReq) input;
        BigDecimal amt = req.getAmount();

        for (SolutionRuleDtl rule : rules) {
            
            BigDecimal fee = amt((SsGpRiskFundConfDtl) rule, amt);
            if (null != fee) {
                res.setDetail(fee);
                break;
            }else{
                res.setDetail(0);
                break;
            }
        }

        

        if (null != res.getDetail()) {
            res.setSolved(true);
        }
        return res;
    }

    /**
     * 计费方式
     * 
     * 0 - 年费 1 - 订单成交金额区间比率收费 2 - 按笔收费 3 - 订单成交金额区间定额收费
     * 
     * @param dtl
     * @param amt
     * @param payChann
     * @param intTxnCd
     * @param acctType
     * @return
     */
    private BigDecimal amt(SsGpRiskFundConfDtl dtl, BigDecimal amt) {

        if (!StringUtils.equals(dtl.getDtlStatus(), FeeDtlStatus._00.value)) {
            return null;
        }
        
        BigDecimal fee = new BigDecimal("0.00");
        
        
        
        String feeType_ = dtl.getFeeType();
        if(null == feeType_){
            logger.error("无效的feeType：" + dtl.toString());
            return null;
        }
        
        // 不收费
        if (feeType_.equals(FeeType._N.value)){
            return fee;
        }
        // 年费
        if (feeType_.equals(FeeType._0.value)){
            return fee;
        }
        // 按笔
        if (feeType_.equals(FeeType._2.value)) {
            return fee.add(new BigDecimal(dtl.getCalExp()));
        }

        // 比例
        if (feeType_.equals(FeeType._1.value)) {
            String[] ranges = StringUtils.split(dtl.getCalExp(), '#');
            for (String range : ranges) {
                String[] param = StringUtils.split(range, '-');
                BigDecimal start = new BigDecimal(param[0]);// 起始
                String endStr = param[1];// 结束
                BigDecimal end = StringUtils.equals("+", endStr) ? new BigDecimal(String.valueOf(Long.MAX_VALUE))
                        : new BigDecimal(endStr);
                if (amt.compareTo(start) >= 0 && amt.compareTo(end) < 0) {
                    BigDecimal sacle = new BigDecimal(param[2]);// 百分比
                    if(sacle.compareTo(NumberUtils.getZero()) > 0){
                        // amt*sacle/100
                        fee = amt.multiply(sacle).divide(new BigDecimal(100));
                    }
                    
                    BigDecimal min = new BigDecimal(param[3]);
                    BigDecimal max = new BigDecimal(param[4]);
                    if (fee.compareTo(min) < 0) {
                        fee = min;
                    }
                    if (fee.compareTo(max) > 0) {
                        fee = max;
                    }
                    if(null == fee || fee.compareTo(NumberUtils.getZero()) < 0){
                    	fee = NumberUtils.getZero();
                    }
                    return fee.setScale(2, BigDecimal.ROUND_HALF_UP);
                }
            }

            logger.error("风险金计算错误，amt: " + amt + ", calExp: " + dtl.getCalExp());
            return null;
        }
        // 定额
        if (feeType_.equals(FeeType._3.value)) {
            String[] ranges = StringUtils.split(dtl.getCalExp(), '#');
            for (String range : ranges) {
                String[] param = StringUtils.split(range, '-');
                BigDecimal start = new BigDecimal(param[0]);// 起始值
                String endStr = param[1];
                BigDecimal end = StringUtils.equals("+", endStr) ? new BigDecimal(String.valueOf(Long.MAX_VALUE))
                        : new BigDecimal(endStr);// 结束值
                if (amt.compareTo(start) >= 0 && amt.compareTo(end) < 0) {
                    fee = fee.add(new BigDecimal(param[2]));
                    return fee;
                }
            }
            logger.error("风险金计算错误，amt: " + amt + ", calExp: " + dtl.getCalExp());
        }
        return null;
    }
}
